home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld files / Utils / SWDitherDown.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-11  |  6.1 KB  |  216 lines  |  [TEXT/CWIE]

  1.  
  2. #include <QDOffScreen.h>
  3. #include "SpriteWorldUtils.h"
  4. #include "SWDitherDown.h"
  5.  
  6. /*
  7.     
  8.     If you create a game using 8-bit graphics, and you:
  9.     A) want the game to be usable on a less-than-8-bit system, although 
  10.     B) not usable on 68000 Macs, and 
  11.     C) rather than creating new graphics for it, want to dither down the 8-bit graphics,
  12.     then these routines will help you out.
  13.  
  14.     Note B) above; SpriteWorld requires Color QuickDraw, which in turn requires a 68020 or 
  15.     higher processor, so your game still won't be playable on a Mac Plus, SE, Mac Classic, etc. 
  16.     These routines use the CopyBits ditherCopy mode. This provides results far superior to
  17.     what you  get from simply using DrawPicture() to draw an 8-bit PICT to a lower-depth GWorld.
  18.     The results are usually still pretty ugly, however.
  19.  
  20.     Warning! no error handling in these routines. Errors might be not enough memory
  21.     to create the GWorlds or to load the pict/cicn or, of course, invalid resID's.
  22.  
  23.  
  24.  
  25.     DitherDownPict; use with either a Sprite made with SWCreateSpriteFromPictResource
  26.     or with SWCreateSpriteFromSinglePict. In the case of SWCreateSpriteFromPictResource,
  27.     pictResID is the ID of a Frame's pict, and destGWorld would be the Frame's framePort:
  28.     
  29.     for (frame = 0; frame < maxFrames; frame++)
  30.     {
  31.         theFrameP = theSprite->frameArray[frame];
  32.         
  33.         DitherDownPict( pictResID+frame, theFrameP->framePort );
  34.     }
  35.     
  36.     For SWCreateSpriteFromSinglePict, you'd just pass the multi-frame pict's ID, and
  37.     the shared GWorld of the Sprite:
  38.     
  39.     DitherDownPict( pictResID, theSprite->sharedPictGWorld );
  40.     
  41.     If you're dithering down tiles, you just have to call this once for a single-pict
  42.     group of tiles. For the destGWorld, use the framePort of any one of the tiles:
  43.     
  44.     DitherDownPict( pictResID, theTile->framePort );
  45.     
  46. */
  47.     
  48. /******************** DitherDownPict ********************/
  49. void DitherDownPict( short pictResID, GWorldPtr destGWorld )
  50. {
  51.  
  52.     GWorldPtr            picGWld,
  53.                         oldGWld;
  54.     GDHandle            oldGDH;
  55.     Rect                picRect;
  56.     PicHandle            thePic;
  57.     GWorldFlags            pixelState;
  58.  
  59.  
  60.     GetGWorld( &oldGWld, &oldGDH );
  61.     
  62.     thePic = GetPicture( pictResID );
  63.     picRect = (**(thePic)).picFrame;
  64.     OffsetRect( &picRect, 0-picRect.left, 0-picRect.top );
  65.     
  66.     (void)NewGWorld( &picGWld, 8, &picRect, nil, nil, 0 );
  67.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  68.     SetGWorld( picGWld, NULL );
  69.     
  70.     DrawPicture( thePic, &picRect );
  71.     ReleaseResource( (Handle)thePic );
  72.     
  73.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  74.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  75.     SetGWorld( destGWorld, NULL );
  76.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  77.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  78.             &picRect,  
  79.             &picRect, ditherCopy, nil);
  80.     
  81.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  82.     DisposeGWorld( picGWld );
  83.     SetGWorld( oldGWld, oldGDH );
  84. }
  85.  
  86.  
  87. /*
  88.     This routine is for when you have a self-masking Sprite created from an 8-bit PICT,
  89.     and want to use it on a lower-depth screen. Using the 8-bit PICT as a pixel mask may
  90.     not work correctly unless you convert the mask afterwards with this. This is called
  91.     much like DitherDownPict, except that the maskPort is passed instead of the framePort:
  92.     
  93.     for (frame = 0; frame < maxFrames; frame++)
  94.     {
  95.         theFrameP = theSprite->frameArray[frame];
  96.         
  97.         LowerMaskDepth( pictResID+frame, theFrameP->maskPort );
  98.     }
  99.     or:
  100.     LowerMaskDepth( pictResID, theSprite->sharedMaskGWorld );
  101. */
  102.     
  103. /******************** LowerMaskDepth ********************/
  104. void LowerMaskDepth( short pictResID, GWorldPtr destGWorld )
  105. {
  106.     GWorldPtr            picGWld,
  107.                         oldGWld;
  108.     GDHandle            oldGDH;
  109.     Rect                picRect;
  110.     PicHandle            thePic;
  111.     GWorldFlags            pixelState;
  112.  
  113.  
  114.     if ( destGWorld == NULL )
  115.         return;
  116.         
  117.     GetGWorld( &oldGWld, &oldGDH );
  118.     
  119.     thePic = GetPicture( pictResID );
  120.     picRect = (**(thePic)).picFrame;
  121.     OffsetRect( &picRect, 0-picRect.left, 0-picRect.top );
  122.     
  123.     (void)NewGWorld( &picGWld, 8, &picRect, nil, nil, 0 );
  124.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  125.     SetGWorld( picGWld, NULL );
  126.     
  127.     DrawPicture( thePic, &picRect );
  128.     ReleaseResource( (Handle)thePic );
  129.  
  130.     SWBlackenGWorld( picGWld );
  131.  
  132.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  133.  
  134.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  135.     SetGWorld( destGWorld, NULL );
  136.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  137.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  138.             &picRect,  
  139.             &picRect, srcCopy, nil);
  140.     InvertRect( &picRect );
  141.  
  142.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  143.  
  144.     DisposeGWorld( picGWld );
  145.     SetGWorld( oldGWld, oldGDH );
  146. }
  147.  
  148.  
  149.  
  150. /*
  151.     DitherDownCicn; use with a Sprite made with SWCreateSpriteFromCicnResource. 
  152.     cicnResID is the ID of a Frame's CIcon, and destGWorld is the Frame's framePort:
  153.     
  154.     for (frame = 0; frame < maxFrames; frame++)
  155.     {
  156.         theFrameP = theSprite->frameArray[frame];
  157.         
  158.         DitherDownCicn( cicnResID+frame, theFrameP->framePort );
  159.     }
  160.     
  161.     Can also be used for tiles made from CIcons:
  162.     
  163.     theFrameP = mySpriteWorldP->tileFrameArray[tileID];
  164.     DitherDownCicn( cicnResID, theFrameP->framePort );
  165.     
  166.     Note that this dithers down the 8-bit color image of the CIcon; it ignores the CIcon's
  167.     black & white image, if any.
  168. */
  169.  
  170. /******************** DitherDownCicn ********************/
  171. void DitherDownCicn( short cicnResID, GWorldPtr destGWorld )
  172. {
  173.  
  174.     GWorldPtr            picGWld,
  175.                         oldGWld;
  176.     GDHandle            oldGDH;
  177.     Rect                frameRect;
  178.     CIconHandle            cIconH;
  179.     GWorldFlags            pixelState;
  180.     
  181.  
  182.     GetGWorld( &oldGWld, &oldGDH );
  183.     
  184.     
  185.     cIconH = GetCIcon( cicnResID );
  186.  
  187.     HLock((Handle)cIconH);
  188.     frameRect = (**cIconH).iconPMap.bounds;
  189.             
  190.     (void)NewGWorld( &picGWld, 8, &frameRect, nil, nil, 0 );
  191.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  192.     SetGWorld( picGWld, NULL );
  193.     
  194.     (**cIconH).iconPMap.baseAddr = *(**cIconH).iconData;                
  195.     CopyBits( (BitMap*)(&((**cIconH).iconPMap)),
  196.         (BitMap*)*GetGWorldPixMap( picGWld ), 
  197.         &frameRect,
  198.         &frameRect, srcCopy, nil);
  199.     DisposeCIcon(cIconH);
  200.     
  201.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  202.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  203.     SetGWorld( destGWorld, NULL );
  204.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  205.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  206.             &frameRect,  
  207.             &frameRect, ditherCopy, nil);
  208.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  209.     
  210.     DisposeGWorld( picGWld );
  211.     SetGWorld( oldGWld, oldGDH );
  212. }
  213.  
  214.  
  215.  
  216.